home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / util / moni / Scout-src.lha / source / objects / scout_timer.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-09-17  |  15.3 KB  |  444 lines

  1. /**
  2.  * Scout - The Amiga System Monitor
  3.  *
  4.  *------------------------------------------------------------------
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  * You must not use this source code to gain profit of any kind!
  21.  *
  22.  *------------------------------------------------------------------
  23.  *
  24.  * @author Andreas Gelhausen
  25.  * @author Richard Körber <rkoerber@gmx.de>
  26.  */
  27.  
  28. #include "system_headers.h"
  29.  
  30. struct TimersCallbackUserData {
  31.     APTR ud_List;
  32.     ULONG ud_Count;
  33. };
  34.  
  35. static __asm __saveds LONG timerlist_con2func(register __a2 Object *obj, register __a1 struct NList_ConstructMessage *msg, register __a0 struct Hook *hook)
  36. {
  37.     return AllocListEntry(msg->pool, msg->entry, sizeof(struct TimerEntry));
  38. }
  39.  
  40. MakeHook(timerlist_con2hook, timerlist_con2func);
  41.  
  42. static __asm __saveds LONG timerlist_des2func(register __a2 Object *obj, register __a1 struct NList_DestructMessage *msg, register __a0 struct Hook *hook)
  43. {
  44.     FreeListEntry(msg->pool, &msg->entry);
  45.  
  46.     return 0;
  47. }
  48.  
  49. MakeHook(timerlist_des2hook, timerlist_des2func);
  50.  
  51. static __asm __saveds LONG timerlist_dsp2func(register __a2 Object *obj, register __a1 struct NList_DisplayMessage *msg, register __a0 struct Hook *hook)
  52. {
  53.     struct TimerEntry *te = (struct TimerEntry *)msg->entry;
  54.  
  55.     if (te) {
  56.         msg->strings[0] = te->te_Address;
  57.         msg->strings[1] = te->te_Name;
  58.         msg->strings[2] = te->te_Timeout;
  59.         msg->strings[3] = te->te_Unit;
  60.         msg->strings[4] = te->te_ReplyPort;
  61.     } else {
  62.         msg->strings[0] = "Address";
  63.         msg->strings[1] = "Task";
  64.         msg->strings[2] = "Time";
  65.         msg->strings[3] = "Unit";
  66.         msg->strings[4] = "mn_ReplyPort";
  67.         msg->preparses[0] = MUIX_B;
  68.         msg->preparses[1] = MUIX_B;
  69.         msg->preparses[2] = MUIX_B;
  70.         msg->preparses[3] = MUIX_B;
  71.         msg->preparses[4] = MUIX_B;
  72.     }
  73.  
  74.     return 0;
  75. }
  76.  
  77. MakeHook(timerlist_dsp2hook, timerlist_dsp2func);
  78.  
  79. static LONG timerlist_cmp2colfunc( struct TimerEntry *te1,
  80.                                    struct TimerEntry *te2,
  81.                                    ULONG column )
  82. {
  83.     switch (column) {
  84.         case 0: return stricmp(te1->te_Address, te2->te_Address);
  85.         case 1: return stricmp(te1->te_Name, te2->te_Name);
  86.         case 2: return stricmp(te1->te_Timeout, te2->te_Timeout);
  87.         case 3: return stricmp(te1->te_Unit, te2->te_Unit);
  88.         case 4: return stricmp(te1->te_ReplyPort, te2->te_ReplyPort);
  89.     }
  90. }
  91.  
  92. static __asm __saveds LONG timerlist_cmp2func(register __a2 Object *obj, register __a1 struct NList_CompareMessage *msg, register __a0 struct Hook *hook)
  93. {
  94.     LONG cmp;
  95.     struct TimerEntry *te1, *te2;
  96.     ULONG col1, col2;
  97.  
  98.     te1 = (struct TimerEntry *)msg->entry1;
  99.     te2 = (struct TimerEntry *)msg->entry2;
  100.     col1 = msg->sort_type & MUIV_NList_TitleMark_ColMask;
  101.     col2 = msg->sort_type2 & MUIV_NList_TitleMark2_ColMask;
  102.  
  103.     if (msg->sort_type == MUIV_NList_SortType_None) return 0;
  104.  
  105.     if (msg->sort_type & MUIV_NList_TitleMark_TypeMask) {
  106.         cmp = timerlist_cmp2colfunc(te2, te1, col1);
  107.     } else {
  108.         cmp = timerlist_cmp2colfunc(te1, te2, col1);
  109.     }
  110.  
  111.     if (cmp != 0 || col1 == col2) return cmp;
  112.  
  113.     if (msg->sort_type2 & MUIV_NList_TitleMark2_TypeMask) {
  114.         cmp = timerlist_cmp2colfunc(te2, te1, col2);
  115.     } else {
  116.         cmp = timerlist_cmp2colfunc(te1, te2, col2);
  117.     }
  118.  
  119.     return cmp;
  120. }
  121.  
  122. MakeHook(timerlist_cmp2hook, timerlist_cmp2func);
  123.  
  124. static void ReceiveList( void (* callback)( struct TimerEntry *te, void *userData ),
  125.                          void *userData )
  126. {
  127.     struct TimerEntry *te;
  128.  
  129.     if (te = tbAllocVecPooled(globalPool, sizeof(struct TimerEntry))) {
  130.         if (SendDaemon("GetTimerList")) {
  131.             while (ReceiveDecodedEntry((UBYTE *)te, sizeof(struct TimerEntry))) {
  132.                 callback(te, userData);
  133.             }
  134.         }
  135.  
  136.         tbFreeVecPooled(globalPool, te);
  137.     }
  138. }
  139.  
  140. static void IterateList( void (* callback)( struct TimerEntry *te, void *userData ),
  141.                          void *userData )
  142. {
  143.     struct MinList tmplist;
  144.     struct TimerEntry *te, *_te;
  145.     struct MsgPort *mp;
  146.  
  147.     NewList((struct List *)&tmplist);
  148.  
  149.     if (mp = CreateMsgPort()) {
  150.         struct timerequest *mytr;
  151.  
  152.         if (mytr = CreateIORequest(mp, sizeof(struct timerequest))) {
  153.             if (OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest *)mytr, 0) == 0) {
  154.                 struct EClockVal eclock;
  155.                 ULONG eclk;
  156.                 struct List *trlist;
  157.                 struct timerequest *tr;
  158.  
  159.                 TimerBase = mytr->tr_node.io_Device;
  160.  
  161.                 mytr->tr_node.io_Command = TR_ADDREQUEST;
  162.                 mytr->tr_time.tv_secs = 0;
  163.                 mytr->tr_time.tv_micro = 10000;
  164.  
  165.                 Forbid();
  166.  
  167.                 SendIO((struct IORequest *)mytr);
  168.  
  169.                 trlist = FindListOfNode((struct Node *)mytr);
  170.  
  171.                 eclk = ReadEClock(&eclock);
  172.                 eclk /= 100;
  173.  
  174.                 ITERATE_LIST(trlist, struct timerequest *, tr) {
  175.                     if (tr != mytr) {
  176.                         if (te = AllocVec(sizeof(struct TimerEntry), MEMF_PUBLIC)) {
  177.                             ULONG  time, std, min, sec;
  178.  
  179.                             time = tr->tr_time.tv_micro;
  180.                             if (time > eclock.ev_lo) {
  181.                                 time -= eclock.ev_lo;
  182.                                 time /= eclk;
  183.                             } else {
  184.                                 time = 0;
  185.                             }
  186.  
  187.                             sec = tr->tr_time.tv_secs + (time / 100);
  188.                             min = sec / 60;
  189.                             sec %= 60;
  190.                             std = min / 60;
  191.                             min %= 60;
  192.  
  193.                             te->te_Addr = tr;
  194.                             _snprintf(te->te_Address, sizeof(te->te_Address), "$%08lx", tr);
  195.                             GetTaskName(tr->tr_node.io_Message.mn_ReplyPort->mp_SigTask, te->te_Name, sizeof(te->te_Name));
  196.                             _snprintf(te->te_ReplyPort, sizeof(te->te_ReplyPort), "$%08lx", tr->tr_node.io_Message.mn_ReplyPort);
  197.                             stccpy(te->te_Unit, "MicroHz", sizeof(te->te_Unit));
  198.                             _snprintf(te->te_Timeout, sizeof(te->te_Timeout), "%ld:%02ld'%02ld.%02ld\"", std, min, sec, time % 100);
  199.  
  200.                             AddTail((struct List *)&tmplist, (struct Node *)te);
  201.                         }
  202.                     }
  203.                 }
  204.  
  205.                 Permit();
  206.  
  207.                 WaitIO((struct IORequest *)mytr);
  208.                 CloseDevice((struct IORequest *)mytr);
  209.             }
  210.  
  211.             if (OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)mytr, 0) == 0) {
  212.                 struct EClockVal eclock;
  213.                 ULONG eclk;
  214.                 struct List *trlist;
  215.                 struct timerequest *tr;
  216.  
  217.                 TimerBase = mytr->tr_node.io_Device;
  218.  
  219.                 mytr->tr_node.io_Command = TR_ADDREQUEST;
  220.                 mytr->tr_time.tv_secs = 0;
  221.                 mytr->tr_time.tv_micro = 20000;
  222.  
  223.                 Forbid();
  224.  
  225.                 SendIO((struct IORequest *)mytr);
  226.  
  227.                 trlist = FindListOfNode((struct Node *)mytr);
  228.  
  229.                 eclk = ReadEClock(&eclock);
  230.  
  231.                 ITERATE_LIST(trlist, struct timerequest *, tr) {
  232.                     if (tr != mytr) {
  233.                         if (te = AllocVec(sizeof(struct TimerEntry), MEMF_PUBLIC)) {
  234.                             ULONG  time, std, min, sec;
  235.  
  236.                             time = tr->tr_time.tv_micro;
  237.                             if (time > eclock.ev_lo) {
  238.                                 time = ((time - eclock.ev_lo) * 100) / eclk;
  239.                             } else {
  240.                                 time = 0;
  241.                             }
  242.  
  243.                             sec = tr->tr_time.tv_secs + (time / 100);
  244.                             min = sec / 60;
  245.                             sec %= 60;
  246.                             std = min / 60;
  247.                             min %= 60;
  248.  
  249.                             te->te_Addr = tr;
  250.                             _snprintf(te->te_Address, sizeof(te->te_Address), "$%08lx", tr);
  251.                             GetTaskName(tr->tr_node.io_Message.mn_ReplyPort->mp_SigTask, te->te_Name, sizeof(te->te_Name));
  252.                             _snprintf(te->te_ReplyPort, sizeof(te->te_ReplyPort), "$%08lx", tr->tr_node.io_Message.mn_ReplyPort);
  253.                             stccpy(te->te_Unit, "VBlank", sizeof(te->te_Unit));
  254.                             _snprintf(te->te_Timeout, sizeof(te->te_Timeout), "%ld:%02ld'%02ld.%02ld\"", std, min, sec, time % 100);
  255.  
  256.                             AddTail((struct List *)&tmplist, (struct Node *)te);
  257.                         }
  258.                     }
  259.                 }
  260.  
  261.                 Permit();
  262.  
  263.                 WaitIO((struct IORequest *)mytr);
  264.                 CloseDevice((struct IORequest *)mytr);
  265.             }
  266.  
  267.             DeleteIORequest((struct IORequest *)mytr);
  268.         }
  269.  
  270.         DeleteMsgPort(mp);
  271.     }
  272.  
  273.     ITERATE_CHANGING_LIST(&tmplist, struct TimerEntry *, te, _te) {
  274.         callback(te, userData);
  275.         FreeVec(te);
  276.     }
  277. }
  278.  
  279. static void UpdateCallback( struct TimerEntry *te,
  280.                             void *userData )
  281. {
  282.     struct TimersCallbackUserData *ud = (struct TimersCallbackUserData *)userData;
  283.  
  284.     InsertSortedEntry(ud->ud_List, te);
  285.     ud->ud_Count++;
  286. }
  287.  
  288. static void PrintCallback( struct TimerEntry *te,
  289.                            void *userData )
  290. {
  291.     PrintFOneLine((BPTR)userData, " %s %s %13s %-7s %s\n", te->te_Address, te->te_ReplyPort, te->te_Timeout, te->te_Unit, te->te_Name);
  292. }
  293.  
  294. static void SendCallback( struct TimerEntry *te,
  295.                           void *userData )
  296. {
  297.     SendEncodedEntry((UBYTE *)te, sizeof(struct TimerEntry));
  298. }
  299.  
  300. static ULONG __saveds mNew( struct IClass *cl,
  301.                             Object *obj,
  302.                             struct opSet *msg )
  303. {
  304.     APTR timerlist, timertext, timercount, updateButton, printButton, exitButton;
  305.  
  306.     if (obj = (Object *)DoSuperNew(cl, obj,
  307.         MUIA_HelpNode, TimerText,
  308.         MUIA_Window_ID, MakeID('T','I','M','R'),
  309.         WindowContents, VGroup,
  310.  
  311.             Child, timerlist = MyNListviewObject(MakeID('T','I','L','V'), "BAR,BAR,BAR,BAR P=" MUIX_C ",BAR", &timerlist_con2hook, &timerlist_des2hook, &timerlist_dsp2hook, &timerlist_cmp2hook, TRUE),
  312.             Child, MyBelowListview(&timertext, &timercount),
  313.  
  314.             Child, MyVSpace(4),
  315.  
  316.             Child, HGroup, MUIA_Group_SameSize, TRUE,
  317.                 Child, updateButton = MakeButton(txtUpdate),
  318.                 Child, printButton  = MakeButton(txtPrint),
  319.                 Child, exitButton   = MakeButton(txtExit),
  320.             End,
  321.         End,
  322.         TAG_MORE, msg->ops_AttrList))
  323.     {
  324.         struct TimersWinData *twd = INST_DATA(cl, obj);
  325.         APTR parent;
  326.  
  327.         twd->twd_TimerList = timerlist;
  328.         twd->twd_TimerText = timertext;
  329.         twd->twd_TimerCount = timercount;
  330.  
  331.         parent = (APTR)GetTagData(MUIA_Window_ParentWindow, (ULONG)NULL, msg->ops_AttrList);
  332.  
  333.         set(obj, MUIA_Window_Title, MyGetWindowTitle("TIMER REQUESTS", twd->twd_Title, sizeof(twd->twd_Title)));
  334.         set(obj, MUIA_Window_ActiveObject, timerlist);
  335.  
  336.         DoMethod(parent,       MUIM_Window_AddChildWindow, obj);
  337.         DoMethod(obj,          MUIM_Notify, MUIA_Window_CloseRequest, TRUE,           MUIV_Notify_Application, 5, MUIM_Application_PushMethod, parent, 2, MUIM_Window_RemChildWindow, obj);
  338.         DoMethod(timerlist,    MUIM_Notify, MUIA_NList_Active,        MUIV_EveryTime, obj,                     1, MUIM_TimersWin_ListChange);
  339.         DoMethod(updateButton, MUIM_Notify, MUIA_Pressed,             FALSE,          obj,                     1, MUIM_TimersWin_Update);
  340.         DoMethod(printButton,  MUIM_Notify, MUIA_Pressed,             FALSE,          obj,                     1, MUIM_TimersWin_Print);
  341.         DoMethod(exitButton,   MUIM_Notify, MUIA_Pressed,             FALSE,          obj,                     3, MUIM_Set, MUIA_Window_CloseRequest, TRUE);
  342.         DoMethod(timerlist,    MUIM_NList_Sort3, MUIV_NList_Sort3_SortType_1, MUIV_NList_SortTypeAdd_None, MUIV_NList_Sort3_SortType_Both);
  343.     }
  344.  
  345.     return (ULONG)obj;
  346. }
  347.  
  348. static ULONG __saveds mDispose( struct IClass *cl,
  349.                                 Object *obj,
  350.                                 struct opSet *msg )
  351. {
  352.     struct TimersWinData *twd = INST_DATA(cl, obj);
  353.  
  354.     set(obj, MUIA_Window_Open, FALSE);
  355.     DoMethod(twd->twd_TimerList, MUIM_NList_Clear);
  356.  
  357.     return (DoSuperMethodA(cl, obj, msg));
  358. }
  359.  
  360. static ULONG __saveds mUpdate( struct IClass *cl,
  361.                                Object *obj,
  362.                                Msg msg )
  363. {
  364.     struct TimersWinData *twd = INST_DATA(cl, obj);
  365.     struct TimersCallbackUserData ud;
  366.  
  367.     ApplicationSleep(TRUE);
  368.     set(twd->twd_TimerList, MUIA_NList_Quiet, TRUE);
  369.     DoMethod(twd->twd_TimerList, MUIM_NList_Clear);
  370.  
  371.     ud.ud_List = twd->twd_TimerList;
  372.     ud.ud_Count = 0;
  373.  
  374.     if (clientstate) {
  375.         ReceiveList(UpdateCallback, &ud);
  376.     } else {
  377.         IterateList(UpdateCallback, &ud);
  378.     }
  379.  
  380.     SetCountText(twd->twd_TimerCount, ud.ud_Count);
  381.     MySetContents(twd->twd_TimerText, "");
  382.  
  383.     set(twd->twd_TimerList, MUIA_NList_Quiet, FALSE);
  384.     ApplicationSleep(FALSE);
  385.  
  386.     return 0;
  387. }
  388.  
  389. static ULONG __saveds mPrint( struct IClass *cl,
  390.                               Object *obj,
  391.                               Msg msg )
  392. {
  393.     PrintTimer(NULL);
  394.  
  395.     return 0;
  396. }
  397.  
  398. static ULONG __saveds mListChange( struct IClass *cl,
  399.                                    Object *obj,
  400.                                    Msg msg )
  401. {
  402.     struct TimersWinData *twd = INST_DATA(cl, obj);
  403.     struct TimerEntry *te;
  404.  
  405.     if (te = (struct TimerEntry *)GetActiveEntry(twd->twd_TimerList)) {
  406.         MySetContents(twd->twd_TimerText, "%s \"%s\"", te->te_Address, te->te_Name);
  407.     }
  408.  
  409.     return 0;
  410. }
  411.  
  412. ULONG __asm __saveds TimersWinDispatcher( register __a0 struct IClass *cl,
  413.                                           register __a2 Object *obj,
  414.                                           register __a1 Msg msg )
  415. {
  416.     switch (msg->MethodID) {
  417.         case OM_NEW:                    return (mNew(cl, obj, (APTR)msg));
  418.         case OM_DISPOSE:                return (mDispose(cl, obj, (APTR)msg));
  419.         case MUIM_TimersWin_Update:     return (mUpdate(cl, obj, (APTR)msg));
  420.         case MUIM_TimersWin_Print:      return (mPrint(cl, obj, (APTR)msg));
  421.         case MUIM_TimersWin_ListChange: return (mListChange(cl, obj, (APTR)msg));
  422.     }
  423.  
  424.     return (DoSuperMethodA(cl, obj, msg));
  425. }
  426.  
  427. void PrintTimer( char *filename )
  428. {
  429.     BPTR handle;
  430.  
  431.     if (handle = HandlePrintStart(filename)) {
  432.         PrintFOneLine(handle, "\n  Address  ReplyPort    Time       Unit    Name\n\n");
  433.         IterateList(PrintCallback, (void *)handle);
  434.     }
  435.  
  436.     HandlePrintStop();
  437. }
  438.  
  439. void SendTimerList( void )
  440. {
  441.     IterateList(SendCallback, NULL);
  442. }
  443.  
  444.